package com.espirit.eap.util.tagAdaptor;

import java.util.HashSet;
import java.util.Map;
import java.util.Set;

import javax.annotation.Resource;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.stereotype.Service;

import com.espirit.eap.pagelayout.Element;
import com.espirit.eap.pagelayout.ElementService;
import com.espirit.eap.pagelayout.ElementService.ElementCallback;
import com.espirit.eap.pagelayout.Layout;
import com.espirit.eap.pagelayout.PageCache;
import com.espirit.eap.pagelayout.PageReference;
import com.espirit.eap.pagelayout.TagInfo;
import com.espirit.eap.sa.LoginUserService;
import com.googlecode.cswish.Config;

@Service
public class TagPageReferenceAdaptor implements TagElementAdaptor<PageReference> {

	private static final Log logger = LogFactory.getLog(TagPageReferenceAdaptor.class);
	
	@Resource
	private TagAdaptorUtil tagAdaptorUtil;
	
	@Resource
	private Config config;
	
	@Resource
	private LoginUserService userService;
	
	@Resource
	private ElementService elementService;
	
	@Override
	public TagInfo getTagProperties(Layout root, PageReference sectionElement, Map<String, Object> context) {
		TagInfo tagInfo = new TagInfo(true);
		String tagName = sectionElement.getTagName();
		tagInfo.setTagName(tagName == null ? "include" : tagName);
		
		Map<String, Object> properties = tagInfo.getTagProperties();
		properties.put("name", tagAdaptorUtil.getName(sectionElement));
		Map<String, String> exProperties = sectionElement.getExProperties();
		if (exProperties != null) {
			properties.putAll(exProperties);
		}
		return tagInfo;
	}

	@Override
	public String getTagName(PageReference element) {
		String tagName = element.getTagName();
		return tagName == null ? "include" : tagName;
	}
	
	@Override
	public PageReference updateToElement(Map<String, String> tagProperties, PageReference existed, Map<String, Object> context, PageCache pageCache) {
		PageReference pageReference = existed;
		String name = tagProperties.get("name");
		existed.setName(name);
		if (existed.getTagName() == null) {
			existed.setTagName("include");
		}
		
		pageReference.setUrl(tagProperties.get("url"));
		return existed;
	}

	@Override
	public Element addElement(Element parent, String tagName, Map<String, Object> properties, PageCache pageCache) {
		Integer index = pageCache.increaseMaxId();
		Layout root = pageCache.getLayout();		
		PageReference pageReference = new PageReference();
		PageReference sectionElement = (PageReference)tagAdaptorUtil.createSectionElement(root, parent, pageReference);
		sectionElement.setId(-index);
		sectionElement.setTagName(tagName);
		
		// name
		String name = tagAdaptorUtil.createName(root, tagName);
		sectionElement.setName(name);
		
		String modelPath = pageCache.getPath();
		int fileNameIndex = modelPath.lastIndexOf('.') + 1;
		String fileExtension;
		boolean isFtl = false;
		if ("script".equals(tagName)) {
			fileExtension = ".js";
		} else if ("css".equals(tagName)) {
			fileExtension = ".css";
		} else {
			fileExtension = ".ftl";
			isFtl = true;
		}
		
		final Set<String> files = new HashSet<>();
		elementService.iterator(pageCache.getLayout().getChildren(), new ElementCallback() {
			@Override
			public boolean process(Element parent, Element element, int deep) {
				String refFile = tagAdaptorUtil.getRefFile(element);
				if (refFile != null) {
					files.add(refFile);
				}
				return false;
			}
		}, 0);
		int fileIndex = 0;
		String url;
		do {
			url = config.getViewDir4GenCode() + modelPath.substring(1, fileNameIndex) + fileIndex + fileExtension;
			fileIndex++;
		} while(files.contains(url));
		
		if (isFtl) {
			sectionElement.setUrl(url);
		} else {
			sectionElement.addExProperty("src", url);
		}
		return sectionElement;
	}

	@Override
	public void deleteElement(Element parent, PageReference existed, PageCache pageCache) {
	}
};